#include "cvariant.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 带动态内存的结构体（需要手动释放）
typedef struct {
    int id;
    char* name;  // 动态分配的字符串（需malloc/free）
    float score;
} DynamicData;


// 复制函数：深度复制动态内存
static void dynamicdata_copy(const void* src, void* dest) {
    const DynamicData* s = (const DynamicData*)src;
    DynamicData* d = (DynamicData*)dest;

    // 复制基础类型
    d->id = s->id;
    d->score = s->score;

    // 复制动态字符串（关键：手动分配新内存）
    if (s->name) {
        d->name = (char*)malloc(strlen(s->name) + 1);  // 分配内存
        strcpy(d->name, s->name);  // 复制内容
    } else {
        d->name = NULL;
    }
}

// 销毁函数：释放动态内存（关键：防止内存泄漏）
static void dynamicdata_destroy(void* data) {
    DynamicData* d = (DynamicData*)data;
    if (d->name) {
        free(d->name);  // 释放动态字符串
        d->name = NULL;  // 避免野指针
    }
}

int main() {
    // 1. 注册自定义类型（带动态内存）
    TypeId dynamic_type = cvariant_register_custom_type(
        sizeof(DynamicData),
        dynamicdata_copy,    // 深度复制动态内存
        dynamicdata_destroy  // 释放动态内存
    );
    printf("注册动态类型 ID: %d\n", dynamic_type);

    // 2. 创建原始数据（带动态内存）
    DynamicData original;
    original.id = 1001;
    original.name = (char*)malloc(strlen("Alice") + 1);  // 手动分配
    strcpy(original.name, "Alice");
    original.score = 95.5f;
    printf("原始数据: id=%d, name=%s, score=%.1f\n", 
           original.id, original.name, original.score);

    // 3. 用变体类型存储动态数据
    struct CVariant* var = cvariant_create();
    cvariant_set_custom(var, dynamic_type, &original);

    // 4. 从变体中读取数据（验证复制是否正确）
    if (cvariant_get_type(var) == dynamic_type) {
        DynamicData copy;
        cvariant_get_custom(var, &copy);
        printf("从变体读取: id=%d, name=%s, score=%.1f\n",
               copy.id, copy.name, copy.score);
    }

    // 5. 清理资源
    // 注意：原始数据的动态内存需要手动释放（变体内部的由destroy处理）
    free(original.name);  // 释放原始数据的name
    cvariant_destroy(var);  // 变体销毁时会自动调用dynamicdata_destroy

    return 0;
}